﻿Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Drawing
Imports MessageBoxEx.My.Resources

<ComVisible(True)>
Public Enum DialogBoxResult
    Button1
    Button2
    Button3
    None
End Enum

<ComVisible(True)>
Public Enum DialogResult
    None = 0
    OK = 1
    Cancel = 2
    Abort = 3
    Retry = 4
    Ignore = 5
    Yes = 6
    No = 7
End Enum

<ComVisible(True)>
Public Enum MsgBoxExImage
    None = 0
    Information = 1
    Question = 2
    Exclamation = 3
    Check = 4
    Cross = 5
    Plus = 6
    Minus = 7
    Clock = 8
    Play = 9
    Find = 10
End Enum

Partial Public Class MsgBoxEx
    Inherits Form

    Public Sub New(msgboxMessage As String, msgboxTitle As String, Optional msgboxUserImage As Bitmap = Nothing,
                   Optional msgboxImage As MsgBoxExImage = MsgBoxExImage.None)

        Dim _image As Bitmap = MsgBoxImages.information

        InitializeComponent()

        msgMessage.Text = msgboxMessage
        Text = msgboxTitle

        If (msgboxUserImage IsNot Nothing) Then

            _image = msgboxUserImage

        End If

        If (msgboxUserImage Is Nothing) And msgboxImage <> MsgBoxExImage.None Then

            Select Case msgboxImage
                Case MsgBoxExImage.Check
                    _image = MsgBoxImages.check
                Case MsgBoxExImage.Clock
                    _image = MsgBoxImages.clock
                Case MsgBoxExImage.Cross
                    _image = MsgBoxImages.cross
                Case MsgBoxExImage.Exclamation
                    _image = MsgBoxImages.exclamation
                Case MsgBoxExImage.Find
                    _image = MsgBoxImages.find
                Case MsgBoxExImage.Minus
                    _image = MsgBoxImages.minus
                Case MsgBoxExImage.Play
                    _image = MsgBoxImages.play
                Case MsgBoxExImage.Plus
                    _image = MsgBoxImages.plus
                Case MsgBoxExImage.Question
                    _image = MsgBoxImages.question
            End Select

        End If

        m_sysImage = _image
    End Sub

#Region "Variables Code"

    Public Sub SetButtons(ParamArray buttonTexts As String())

        Dim results As DialogResult() = New DialogResult(buttonTexts.Length) {}
        Dim i As Integer = 0

        While i < buttonTexts.Length

            results(i) = DialogResult.None
            i = i + 1

        End While

        SetButtons(buttonTexts, results)
    End Sub

    Public Sub SetButtons(buttonTexts As String(), results As DialogResult())

        Me.SetButtons(buttonTexts, results, 1)
    End Sub

    Public Sub SetButtons(buttonTexts As String(), buttonReturn As DialogResult(), buttonDefault As Integer)

        If buttonTexts Is Nothing Then

            Throw New ArgumentNullException("buttonTexts", "Button Text is null")

        End If

        Dim count As Integer = buttonTexts.Length

        If count < 1 OrElse count > 3 Then

            Throw New ArgumentException("Invalid number of buttons. Must be between 1 and 3.")

        End If

        m_minButtonRowWidth += SetButton_Params(msgButton1, buttonTexts(0), If(buttonDefault = 1, 1, 2), buttonReturn(0))

        If count = 1 Then

            msgButton1.Focus()

        ElseIf count - 2 Then

            m_minButtonRowWidth +=
                SetButton_Params(msgButton2, buttonTexts(1), If(buttonDefault = 2, 1, 3), buttonReturn(1)) +
                BUTTON_SPACE

            msgButton2.Focus()

        ElseIf count = 3 Then

            m_minButtonRowWidth +=
                SetButton_Params(msgButton3, buttonTexts(2), If(buttonDefault = 3, 1, 4), buttonReturn(2)) +
                BUTTON_SPACE

            msgButton3.Focus()

        End If
    End Sub

    Private m_minButtonRowWidth As Integer

    Shared Function SetButton_Params(btn As Button, text As String, tab As Integer, dr As DialogResult) As Integer

        btn.Text = text
        btn.Visible = True
        btn.DialogResult = dr
        btn.TabIndex = tab

        Return btn.Size.Width
    End Function

    Public Property checkboxText() As String

        Get

            Return msgCheckbox.Text
        End Get

        Set(value As String)

            msgCheckbox.Visible = True

            msgCheckbox.Text = value
        End Set
    End Property

    Public Property checkboxValue() As Boolean

        Get

            Return msgCheckbox.Checked
        End Get

        Set(value As Boolean)

            msgCheckbox.Checked = value
        End Set
    End Property

#End Region

#Region "Size and Locations"

    Private Sub MsgBoxExtended_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        If Not msgButton1.Visible Then

            SetButtons(New String() {"OK"}, New DialogResult() {DialogResult.OK})

        End If

        m_minButtonRowWidth += 2 * FORM_X_MARGIN

        SetButtons_Position()

        Form_Resize()
    End Sub

    Const FORM_X_MARGIN As Integer = 12
    Const BUTTON_SPACE As Integer = 5
    Const CHECKBOX_SPACE As Integer = 15
    Const TEXT_Y_MARGIN As Integer = 30

    Sub Form_Resize()

        If (msgMessage.Height > 74) Then

            If msgButton3.Visible = True Then

                msgMessage.Width = (msgButton3.Left + msgButton3.Width)

            ElseIf msgButton2.Visible = True Then

                msgMessage.Width = (msgButton2.Left + msgButton2.Width)

            ElseIf msgButton1.Visible = True Then

                msgMessage.Width = (msgButton1.Left + msgButton1.Width)

            End If

        End If

        Dim _reqWidth As Integer = msgMessage.Location.X + msgMessage.Size.Width + FORM_X_MARGIN
        _reqWidth = If(_reqWidth > m_minButtonRowWidth, _reqWidth, m_minButtonRowWidth)

        Dim _reqHeight As Integer = msgMessage.Height + msgButton1.Height + TEXT_Y_MARGIN + 16

        Dim _width As Integer = If(ClientSize.Width > MinimumSize.Width, ClientSize.Width, MinimumSize.Width)
        Dim _height As Integer = If(ClientSize.Height > MinimumSize.Height, ClientSize.Height, MinimumSize.Height)

        Dim _size As New Size()

        _size.Width = If(_reqWidth > _width, _reqWidth, _width)
        _size.Height = If(_reqHeight > _height, _reqHeight, _height)

        ClientSize = _size
    End Sub

    Private Sub SetButtons_Position()

        Dim _width As Integer = ClientRectangle.Width

        Dim _left As Integer = _width - FORM_X_MARGIN
        Dim _top As Integer = msgButton1.Location.Y

        If msgButton3.Visible Then
            _left -= msgButton3.Size.Width
            msgButton3.Location = New Point(_left, _top)
            _left -= BUTTON_SPACE
        End If

        If msgButton2.Visible Then
            _left -= msgButton2.Size.Width
            msgButton2.Location = New Point(_left, _top)
            _left -= BUTTON_SPACE
        End If

        _left -= msgButton1.Size.Width

        msgButton1.Location = New Point(_left, _top)

        If msgCheckbox.Visible Then

            msgCheckbox.Location = New Point(FORM_X_MARGIN, msgCheckbox.Location.Y)

        End If
    End Sub

#End Region

#Region "Icon Paint"

    Private m_sysImage As Image

    Protected Overrides Sub OnPaint(e As PaintEventArgs)

        If (m_sysImage IsNot Nothing) Then

            msgImage.Image = m_sysImage

        End If

        MyBase.OnPaint(e)

        Update()
    End Sub

#End Region

#Region "Return Code"

    Private m_result As DialogBoxResult = DialogBoxResult.None

    Public ReadOnly Property DialogBoxResult() As DialogBoxResult

        Get

            Return m_result

        End Get

    End Property

    Private Sub btn_Click(sender As Button)

        m_result = sender.DialogResult

        Me.Close()

    End Sub

    Private Sub msgButton_Click(sender As Object, e As EventArgs) _
        Handles msgButton1.Click, msgButton2.Click, msgButton3.Click

        btn_Click(sender)

    End Sub

#End Region
End Class